﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace 聊天室
{
    public partial class Form1 : Form
    {
        List<Socket> skList = new List<Socket>();
        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 设置服务器监听IP地址和端口号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Socketbutton_Click(object sender, EventArgs e)
        {

            Socket sk = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            IPAddress ip = IPAddress.Any;
            IPEndPoint point = new IPEndPoint(ip,Convert.ToInt32(PointtextBox.Text));
            sk.Bind(point);
            Speakbox("服务器开启成功准备监听聊天室内容ing");
            //设置服务器人数
            sk.Listen(10);
           
            Thread th = new Thread(listen);
            th.IsBackground = true;
            th.Start(sk);

           
        }
        /// <summary>
        /// 循环监听
        /// </summary>
        /// <param name="sk"></param>
        private void listen(object sk) {
            try {
                Socket sks = sk as Socket;
                while (true)
                {
                    //设计并生成接收服务器
                    Socket sksnow = sks.Accept();
                    Speakbox(sksnow.RemoteEndPoint.ToString() + ":" + "连接成功");
                    skList.Add(sksnow);
                    //给接收信息开一个新线程防止无法接收到后续客户端
                    Thread th = new Thread(listenText);
                    th.IsBackground = true;
                    th.Start(sksnow);
                }
            } catch { }
            
        }
        /// <summary>
        /// 循环接收信息
        /// </summary>
        /// <param name="sk"></param>
        private void listenText(object sk) {
            try {
                Socket sks = sk as Socket;
                while (true)
                {
                    //设置一次接收的字符串数
                    byte[] bt = new byte[1024 * 1024 * 10];
                    //接收的数据
                    int r = sks.Receive(bt);
                    if (r == 0) return;
                    if (bt[0] == 3)
                    {
                        Speakbox(sks.RemoteEndPoint.ToString() + ":" + "发了一个文件");
                        String FileInput = Encoding.UTF8.GetString(bt, 0, r);
                        //利用正则表达式取出id
                        Match match = Regex.Match(FileInput, @"\(([^)]+)\)"); 
                        string content = match.Groups[1].Value;
                        // 移除括号及其内容，保留其他部分
                        string result = Regex.Replace(FileInput, @"\([^)]*\)", "");
                        byte[] newbuffer = Encoding.UTF8.GetBytes(result.ToCharArray(), 0, result.ToCharArray().Length);
                        foreach (Socket skl in skList)
                        {
                            if (skl.RemoteEndPoint.ToString().Equals(content)) skl.Send(newbuffer);
                        }
                    }
                    else {
                        String text = Encoding.UTF8.GetString(bt, 0, r);
                        Speakbox(sks.RemoteEndPoint.ToString() + ":" + text+"非文本信息");
                        byte[] Zhuanfa = Encoding.UTF8.GetBytes(sks.RemoteEndPoint.ToString() + "：" + text.Split('给')[0] + "\r\n");
                        //转发给客户端发送的消息到另一个客户端
                        foreach (Socket skl in skList)
                        {
                            if (skl.RemoteEndPoint.ToString().Equals(text.Split('给')[1])) skl.Send(Zhuanfa);
                        }
                    }
                }
            }catch (Exception ex)
            {
                // 处理所有未被前面的catch捕获的异常
                Speakbox("发生了一个异常: " + ex.Message);
            }

        }
        /// <summary>
        /// 给聊天室窗口加入文本显示
        /// </summary>
        private void Speakbox(object speaktext) {
            SpeakTextbox.Text += speaktext as String+"\r\n";
        }
        /// <summary>
        /// 关闭跨线程访问限制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            CheckForIllegalCrossThreadCalls = false;
        }

        private void IPtextBox_TextChanged(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// 每两秒更新在线信息，并通知给客户端
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            try {
                //确保给每个客户端都发送
                foreach (Socket sk in skList)
                {
                    String Sockets = "";
                    foreach (Socket s in skList)
                    {
                        Sockets += (s.RemoteEndPoint.ToString()) + "\r\n";
                    }

                    byte[] by = Encoding.UTF8.GetBytes(Sockets.ToCharArray());
                    sk.Send(by);
                    
                }
            } catch {
                //捕获到异常是因为有客户端登出，直接清空该回收站
                foreach (Socket sk in skList)
                {
                    sk.Close();
                    skList.Remove(sk);
                }
            }
           
        }
    }
}
